package com.guang.syncronized;

import com.guang.syncronized.domain.A;
import org.openjdk.jol.info.ClassLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * @Description 升级成为重量级锁  首先设置偏向锁延迟为0 -XX:BiasedLockingStartupDelay=0
 * @Author liguang
 * @Date 2022/10/19/10:36
 */
public class SyncronziedDemoEight {
    private final static Logger logger = LoggerFactory.getLogger(SyncronziedDemoEight.class);
    static A lock  = new A();
    public static void main(String[] args) {

        logger.info("因为关闭了偏向延迟，所以当前对象头中的信息是101，表示可偏向");
        logger.info(ClassLayout.parseInstance(lock).toPrintable());
        logger.info("当前主线程持有锁,所以有了偏向线程main，101，有了偏向线程ID");
        synchronized (lock){
            logger.info(ClassLayout.parseInstance(lock).toPrintable());
        }

        Thread t1 = new Thread(() -> {
            logger.info("偏向锁保存的是main线程的ID，因为当前是t1线程，发生线程撤销，升级成轻量级锁，不可偏向，000");
            synchronized (lock) {
                try {
                    logger.info(ClassLayout.parseInstance(lock).toPrintable());
                    TimeUnit.MICROSECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t1");
        t1.start();

        try {
            TimeUnit.MICROSECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("让线程睡眠是为了能够产生竞争，此时锁是轻量级锁 000");
        logger.info(ClassLayout.parseInstance(lock).toPrintable());
        Thread t3 = new Thread(() -> {
            synchronized (lock) {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t3");
        t3.start();
        try {
            TimeUnit.MICROSECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                logger.info("因为t2在等待t1的过程中出现了线程竞争，所以造成了锁升级，膨胀成重量级锁 010");
                logger.info("当前的锁的状态是：{}",ClassLayout.parseInstance(lock).toPrintable());
            }
        }, "t2");
        t2.start();
    }

}
